package view;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;

import common.Contexto;
import controller.PrendaController;
import model.Material;
import model.Prenda;
import model.PrendaTemporada;


@SuppressWarnings("serial")
public class PrendaPanel extends JPanel {

	private JButton guardarB, eliminarB, volverB;
	private JCheckBox esTemporadaCB;
	@SuppressWarnings("rawtypes")
	private JComboBox temporadaC;
	private JLabel codigoL, nombreL, cantidadStockL, materialesL;
	private JScrollPane materialesSP;
	private JSpinner cantidadStockS;
	private JTable materialesT;
	private JTextField codigoT, nombreT;
	private MaterialesTableModel tableModel;
	private boolean update = false;
	private Prenda prenda;
	
	public PrendaPanel(List<Material> materiales) {
		this.tableModel = new MaterialesTableModel(materiales);
		initGui();
		layoutComponents();
		initActions();
	}

	public PrendaPanel(List<Material> materiales, Prenda prenda) {
		this(materiales);
		setPrenda(prenda);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void initGui() {
		codigoL = new JLabel("* Codigo");
		nombreL = new JLabel("* Nombre");
		cantidadStockL = new JLabel("Cantidad en stock:");
		materialesL = new JLabel("Materiales:");

		cantidadStockS = new JSpinner(new SpinnerNumberModel(1,0,10000,1));
		
		esTemporadaCB = new JCheckBox("Temporada");
		
		String[] temporadaCValues = new String[] { "Verano", "Primavera", "Invierno", "Otono"};
		temporadaC = new JComboBox(temporadaCValues);
		temporadaC.setVisible(false);
		volverB = new JButton("Volver");
		guardarB = new JButton("Guardar");
		eliminarB = new JButton("Eliminar");
		eliminarB.setVisible(false);

		codigoT = new JTextField(10);
		nombreT = new JTextField(10);
		
		materialesT = new JTable(tableModel);
		materialesT.setPreferredScrollableViewportSize(new Dimension(300,200));
		materialesSP = new JScrollPane(materialesT);

	}

	

	private void layoutComponents() {
		this.setLayout(new GridBagLayout());

		GridBagConstraints c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 0;
		c.anchor = GridBagConstraints.WEST;
		c.fill = GridBagConstraints.BOTH;
		c.insets = new Insets(0, 2, 2, 4);
		add(codigoL, c);

		c.gridy = GridBagConstraints.RELATIVE;
		add(nombreL, c);
		add(cantidadStockL, c);
		add(esTemporadaCB, c);
		c.ipady = 20;
		add(materialesL, c);

		c.gridx = 1;
		c.gridy = 0;
		c.ipady = 0;
		c.anchor = GridBagConstraints.WEST;
		c.fill = GridBagConstraints.BOTH;
		c.insets = new Insets(0, 2, 2, 4);
		c.ipadx = 100;
		add(codigoT, c);

		c.gridy = GridBagConstraints.RELATIVE;
		add(nombreT, c);
		add(cantidadStockS, c);
		add(temporadaC, c);


		c.gridx = 0;
		c.gridy = 5;
		c.gridwidth = 5;
		c.ipadx = 120;
		c.ipady = 100;
		add(materialesSP, c);
		
		c.gridx = 0;
		c.gridy = 9;
		c.gridwidth = 1;
		c.gridheight = 1;
		c.ipady = 0;
		c.insets = new Insets(20, 0, 20, 0);

		
		add(guardarB, c);
		c.gridx = 1;
		add(eliminarB, c);
		c.gridx = 2;
		add(volverB, c);

	}

	private void initActions() {
		guardarB.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (validateFields()) {
					boolean guardado = guardarPrenda();
					clearFields();
					SwingUtilities.windowForComponent(PrendaPanel.this).dispose();
					if(guardado) {
						notificarMensaje("La prenda fue guardada con exito");
					} else {
						notificarError("Ocurrio un error, no pudo guardarse la prenda");
					}
					

				}
			}
		});
		
		eliminarB.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				int n = JOptionPane.showConfirmDialog(
					    PrendaPanel.this,
					    "Esta seguro que desea eliminar la prenda?",
					    "Alerta",
					    JOptionPane.YES_NO_OPTION);
				if(n == JOptionPane.YES_OPTION) {
					boolean eliminado = eliminarPrenda();
					if(eliminado) {
						notificarMensaje("La prenda fue eliminada con exito");
					} else {
						notificarError("Ocurrio un error, no pudo eliminarse la prenda");
					}
					SwingUtilities.windowForComponent(PrendaPanel.this).dispose();
				}
			}
		});

		volverB.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				SwingUtilities.windowForComponent(PrendaPanel.this).dispose();
				clearFields();
			}
		});
		
		esTemporadaCB.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				boolean visible = esTemporadaCB.isSelected();
				temporadaC.setVisible(visible);
			}
		});
	}
	
	private boolean guardarPrenda() {
		boolean result = false;
		String nombre = nombreT.getText();
		String codigo = codigoT.getText();
		int cantidadStock = (Integer) cantidadStockS.getValue();
		Map<Material, Integer> materiales = tableModel.getMaterialesSeleccionados();
		
		if(esTemporadaCB.isSelected()) {
			String temporada = (String)temporadaC.getSelectedItem();
			if(update) {
				result = PrendaController.getInstance().modificacionPrendaTemporada(prenda.getCodigo(), codigo, nombre, materiales, cantidadStock, temporada);
			}else {
				result = PrendaController.getInstance().altaPrendaTemporada(codigo, nombre, materiales, cantidadStock, temporada);
			}
		}else {
			if(update) {
				result = PrendaController.getInstance().modificacionPrendaSinTemporada(prenda.getCodigo(), codigo, nombre, materiales, cantidadStock);
			}else {
				result = PrendaController.getInstance().altaPrendaSinTemporada(codigo, nombre, materiales, cantidadStock);
			}
			
		}
		
		return result;
	}
	
	private boolean eliminarPrenda() {
		boolean result = PrendaController.getInstance().bajaPrenda(prenda.getCodigo());
		return result;
	}
	
	public void showPanel() {
		final JFrame mainFrame = new JFrame();
		mainFrame.setTitle("Nueva Prenda");
		mainFrame.getContentPane().add(this);
		mainFrame.setPreferredSize(new Dimension(700, 380));
		mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		mainFrame.pack();
		mainFrame.setLocationRelativeTo(null);
		mainFrame.setVisible(true);
	}

	private boolean validateFields() {
		
		String nombreV = nombreT.getText();
		String codigoV = codigoT.getText();

		if (nombreV.length() == 0 || codigoV.length() == 0) {
			notificarError("Por favor complete todos los campos obligatorios marcados con *");
			return false;
		}

		return true;
	}

	private void clearFields() {
		nombreT.setText("");
		codigoT.setText("");
		temporadaC.setSelectedIndex(0);
		cantidadStockS.setValue(1);
	}
	
	private void notificarMensaje(String mensaje) {
		Contexto.displayFeedbackMessage(PrendaPanel.this, mensaje);
	}
	
	private void notificarError(String error) {
		Contexto.displayErrorMessage(PrendaPanel.this,error);
	}
	
	public void actualizarMateriales(List<Material> materiales) {
		tableModel.setMateriales(materiales);
	}

	private void setPrenda(Prenda prenda) {
		update = true;
		this.prenda = prenda;
		eliminarB.setVisible(true);
		codigoT.setText(prenda.getCodigo());
		nombreT.setText(prenda.getNombre());
		cantidadStockS.setValue(prenda.getCantidadStock());
		esTemporadaCB.setEnabled(false);//No permitimos la modificacion de Tipo de Prenda
		if(prenda instanceof PrendaTemporada) {
			PrendaTemporada prendaT = (PrendaTemporada) prenda;
			temporadaC.setSelectedItem(prendaT.getTemporada());
			temporadaC.setVisible(true);
			esTemporadaCB.setSelected(true);
		}
		
		tableModel.setMaterialesPrenda(prenda.getMaterialesPrenda());
	}

}